package com.ruoyi.training.service.impl;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.training.domain.*;
import com.ruoyi.training.dto.certificate.SpecialCertificateDto;
import com.ruoyi.training.dto.certificate.SpecialCertificateImport;
import com.ruoyi.training.dto.registration.RegistrationImport;
import com.ruoyi.training.mapper.*;
import com.ruoyi.training.service.ISpecialCertificateService;
import com.ruoyi.training.service.IStudentsService;
import com.ruoyi.training.util.xuehua.SnowflakeIdUtils;
import com.ruoyi.training.vo.certificate.SpecialCertificateVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 特设证书管理Service业务层处理
 *
 * @author hcc
 * @date 2025-11-06
 */
@Service
public class SpecialCertificateServiceImpl implements ISpecialCertificateService {
    @Autowired
    private SpecialCertificateMapper specialCertificateMapper;

    @Autowired
    private StudentsMapper studentsMapper;

    @Autowired
    private RegistrationMapper registrationMapper;

    @Autowired
    private PaymentRecordMapper paymentRecordMapper;

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private ProjectsMapper projectsMapper;

    @Autowired
    private UnitsMapper unitsMapper;

    @Autowired
    private CertificateIssueMapper certificateIssueMapper;

    IStudentsService iStudentsService = SpringUtils.getBean(IStudentsService.class);

    /**
     * 查询特设证书管理
     *
     * @param specialCertificateId 特设证书管理主键
     * @return 特设证书管理
     */
    @Override
    public SpecialCertificate selectSpecialCertificateBySpecialCertificateId(String specialCertificateId) {
        return specialCertificateMapper.selectSpecialCertificateBySpecialCertificateId(specialCertificateId);
    }

    /**
     * 查询特设证书管理列表
     *
     * @param specialCertificate 特设证书管理
     * @return 特设证书管理
     */
    @Override
    public List<SpecialCertificate> selectSpecialCertificateList(SpecialCertificate specialCertificate) {
        return specialCertificateMapper.selectSpecialCertificateList(specialCertificate);
    }

    /**
     * 新增特设证书管理
     *
     * @param specialCertificate 特设证书管理
     * @return 结果
     */
    @Override
    public int insertSpecialCertificate(SpecialCertificate specialCertificate) {
        specialCertificate.setSpecialCertificateId(String.valueOf(new SnowflakeIdUtils(5, 8).nextId()));
        return specialCertificateMapper.insertSpecialCertificate(specialCertificate);
    }

    /**
     * 修改特设证书管理
     *
     * @param specialCertificate 特设证书管理
     * @return 结果
     */
    @Override
    public int updateSpecialCertificate(SpecialCertificate specialCertificate) {
        return specialCertificateMapper.updateSpecialCertificate(specialCertificate);
    }

    /**
     * 批量删除特设证书管理
     *
     * @param specialCertificateIds 需要删除的特设证书管理主键
     * @return 结果
     */
    @Override
    public int deleteSpecialCertificateBySpecialCertificateIds(String[] specialCertificateIds) {
        return specialCertificateMapper.deleteSpecialCertificateBySpecialCertificateIds(specialCertificateIds);
    }

    /**
     * 删除特设证书管理信息
     *
     * @param specialCertificateId 特设证书管理主键
     * @return 结果
     */
    @Override
    public int deleteSpecialCertificateBySpecialCertificateId(String specialCertificateId) {
        return specialCertificateMapper.deleteSpecialCertificateBySpecialCertificateId(specialCertificateId);
    }

    /**
     * 查询特设证书管理列表
     *
     * @param specialCertificateVo 特设证书管理
     * @return 特设证书管理
     */
    @Override
    public List<SpecialCertificateDto> getSpecialCertificateList(SpecialCertificateVo specialCertificateVo) {
        List<SpecialCertificateDto> specialCertificateList = specialCertificateMapper.getSpecialCertificateList(specialCertificateVo);
        List<SpecialCertificateDto> specialCertificateDtos = specialCertificateList.stream().map(specialCertificateDto -> {
            Projects projects = projectsMapper.selectProjectsByProjectId(specialCertificateDto.getProjectId());
            if (projects != null) {
                specialCertificateDto.setProjectName(projects.getProjectName());
            }
            if (StringUtils.isNotEmpty(specialCertificateDto.getInvoiceId())) {
                Invoice invoice = invoiceMapper.selectInvoiceByInvoiceId(specialCertificateDto.getInvoiceId());
                if (invoice != null) {
                    specialCertificateDto.setInvoiceStatus(invoice.getInvoiceStatus());
                }
            }
            if (StringUtils.isNotEmpty(specialCertificateDto.getPaymentId())) {
                PaymentRecord paymentRecord = paymentRecordMapper.selectPaymentRecordByPaymentRecordId(specialCertificateDto.getPaymentId());
                if (paymentRecord != null) {
                    specialCertificateDto.setPaymentState(paymentRecord.getPaymentState());
                    specialCertificateDto.setSpecialCertificateFee(paymentRecord.getPaymentAmount());
                }
            }
            return specialCertificateDto;
        }).collect(Collectors.toList());
        return specialCertificateDtos;
    }

    /**
     * 导入证书信息
     *
     * @param certificateImportList
     * @return
     */
    @Override
    public String importCertificate(List<SpecialCertificateImport> certificateImportList) {
        if (StringUtils.isNull(certificateImportList) || certificateImportList.size() == 0){
            throw new ServiceException("导入报名信息不能为空");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (SpecialCertificateImport specialCertificateImport : certificateImportList) {
            try {
                SpecialCertificate specialCertificate = new SpecialCertificate();
                CertificateIssue certificateIssue = new CertificateIssue();
                BeanUtils.copyProperties(specialCertificateImport,certificateIssue);
                BeanUtils.copyProperties(specialCertificateImport,specialCertificate);
                // 导入单位信息
                Units unit = new Units();
                Students students = new Students();
                if (StringUtils.isNotEmpty(specialCertificateImport.getUnitName())){
                    BeanUtils.copyProperties(specialCertificateImport,unit);
                    Units units = unitsMapper.selectUnitsByUnitName(specialCertificateImport.getUnitName());
                    if (StringUtils.isNull(units))
                    {
                        unit.setUnitId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
                        unit.setCreateTime(DateUtils.getNowDate());
                        unit.setCreateBy(SecurityUtils.getUsername());
                        unitsMapper.insertUnits(unit);
                    }else {
                        if (hasUpdates(unit,units,unitImportString)){
                            unit.setUnitId(units.getUnitId());
                            unit.setCreateTime(units.getCreateTime());
                            unit.setUpdateTime(DateUtils.getNowDate());
                            unitsMapper.updateUnits(unit);
                        }
                    }
                }
                String certTypeDisplay = specialCertificateImport.getDocumentType();
                if (StringUtils.isEmpty(certTypeDisplay)) {
                    throw new ServiceException("证件类型不能为空");
                }
                String documentType = CERT_TYPE_MAP.get(certTypeDisplay.trim());
                String educationDisplay = specialCertificateImport.getQualification(); // 导入的显示值（如“本科”）
                if (StringUtils.isEmpty(educationDisplay)) {
                    throw new ServiceException("学历不能为空");
                }
                String qualification = EDUCATION_MAP.get(educationDisplay.trim());
                // 导入学员信息
                BeanUtils.copyProperties(specialCertificateImport,students);
                Students studentsDb = studentsMapper.checkUserIdNumber(specialCertificateImport.getIdNumber());
                if (StringUtils.isNull(studentsDb)){
                    int i = iStudentsService.insertStudentsWithUser(students);
                    if (i > 0){
                        Students studentsByIdNumber = studentsMapper.checkUserIdNumber(specialCertificateImport.getIdNumber());
                        certificateIssue.setStudentId(studentsByIdNumber.getStudentId());
                        specialCertificate.setStudentId(studentsByIdNumber.getStudentId());
                    }

                }else {
                    if (hasUpdates(students,studentsDb,studentString)){
                        students.setStudentId(studentsDb.getStudentId());
                        students.setUpdateTime(DateUtils.getNowDate());
                        students.setDocumentType(documentType);
                        students.setQualification(qualification);
                        students.setUpdateBy(SecurityUtils.getUsername());
                        students.setUnitId(unit.getUnitId());
                        iStudentsService.updateStudentsWithUser(students);
                    }
                    certificateIssue.setStudentId(studentsDb.getStudentId());
                    specialCertificate.setStudentId(studentsDb.getStudentId());
                }

                // 导入项目信息
                Projects projects = projectsMapper.selectProjectsByName(specialCertificateImport.getProjectName());
                if (StringUtils.isNotNull(projects)){
                    specialCertificate.setProjectId(projects.getProjectId());
                    certificateIssue.setProjectId(projects.getProjectId());
                }
                String trainTypeDisplay = specialCertificateImport.getTrainingType(); // 导入的显示值（如“复审”）
                if (StringUtils.isEmpty(trainTypeDisplay)) {
                    throw new ServiceException("培训类别不能为空");
                }
                String trainingType = TRAIN_TYPE_MAP.get(trainTypeDisplay.trim());
                specialCertificate.setCertificateType(trainingType);
                certificateIssue.setCertificateType(trainingType);
                Projects projectsSpecial = projectsMapper.selectProjectsByName("特种设备");
                Projects projectsType = projectsMapper.selectProjectsByProjectId(projects.getpId());
                boolean contains = projects.getAncestors().contains(projectsSpecial.getProjectId());
                if (!contains) {
                    // 查询发证信息
                    CertificateIssue certificateIssueDb = certificateIssueMapper.getByStudentIdAndProjectId(students.getStudentId(), projects.getProjectId());
                    if (StringUtils.isNotNull(certificateIssueDb)) {
                        certificateIssue.setOriginalCertificateNo(certificateIssueDb.getCertificateNo());
                        certificateIssue.setOriginalValidityStart(certificateIssueDb.getValidityStart());
                        certificateIssue.setOriginalValidityEnd(certificateIssueDb.getValidityEnd());
                    }
                    certificateIssue.setCertificateIssueId(String.valueOf(new SnowflakeIdUtils(5, 8).nextId()));
                    certificateIssue.setCreateBy(SecurityUtils.getUsername());
                    certificateIssue.setCreateTime(DateUtils.getNowDate());
                    certificateIssue.setCertificateType("2");  // 设置证书类型为复审换证
                    certificateIssue.setDigitalStatus("3"); // 设置证书状态为待发
                    certificateIssue.setPaperStatus("3");  // 设置证书状态为待发
                    certificateIssueMapper.insertCertificateIssue(certificateIssue);
                } else {
                    BeanUtils.copyProperties(specialCertificateImport, specialCertificate);
                    specialCertificate.setCertificateType("2");
                    specialCertificate.setWorkCategory(projectsType.getProjectName());
                    specialCertificate.setWorkProject(projects.getProjectName());
                    specialCertificate.setSpecialCertificateId(String.valueOf(new SnowflakeIdUtils(5, 8).nextId()));
                    specialCertificateMapper.insertSpecialCertificate(specialCertificate);
                }

                successNum++;
                successMsg.append("<br/>" + successNum + "、账号 " + specialCertificateImport.getStudentName() + " 导入成功");
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 " + specialCertificateImport.getStudentName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 比较两个对象，只检查指定集合中的字段
     */
    private boolean hasUpdates(Object source, Object target, Set<String> fields) {
        for (String fieldName : fields) {
            try {
                // 获取字段并设置可访问
                Field field = source.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);

                // 获取两个对象的字段值
                Object newValue = field.get(source);
                Object oldValue = field.get(target);

                // 处理两个值都为null的情况
                if (newValue == null && oldValue == null) {
                    continue; // 两者均为null，视为相等，继续检查下一个字段
                }
                // 处理其中一个为null的情况
                if (newValue == null || oldValue == null) {
                    return true; // 一个为null另一个非null，说明有更新
                }
                // 两个均非null，使用equals比较
                if (!newValue.equals(oldValue)) {
                    return true;
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                continue;
            }
        }
        return false;
    }

    private static final Set<String> unitString = new HashSet<>();
    static {
        unitString.add("unitName");
        unitString.add("socialCreditCode");
        unitString.add("administrativeArea");
        unitString.add("unitNature");
        unitString.add("contact");
        unitString.add("unitPhonenumber");
    }

    private static final Set<String> studentString = new HashSet<>();
    static {
        studentString.add("studentName");
        studentString.add("phonenumber");
        studentString.add("certificateStarttime");
        studentString.add("certificateEndtime");
        studentString.add("userType");
        studentString.add("certificateType");
        studentString.add("sex");
        studentString.add("birthDate");
        studentString.add("nation");
        studentString.add("position");
        studentString.add("qualification");
        studentString.add("graduatedFrom");
        studentString.add("major");
        studentString.add("address");
        studentString.add("email");
        studentString.add("fax");
        studentString.add("postCode");
        studentString.add("idNumber");
    }
    private static final Set<String> unitImportString = new HashSet<>();
    static {
        unitImportString.add("unitName");
        unitImportString.add("unitAddress");
        unitImportString.add("contact");
        unitImportString.add("unitPhonenumber");
    }

    private static final Set<String> studentImportString = new HashSet<>();
    static {
        studentImportString.add("studentName");
        studentImportString.add("phonenumber");
        studentImportString.add("certificateType");
        studentImportString.add("idNumber");
        studentImportString.add("qualification");
        studentImportString.add("address");
        studentImportString.add("postCode");
    }


    // 新增：定义字典常量（显示值→编码映射，根据实际业务填写正确的键值对）
    private static final Map<String, String> CERT_TYPE_MAP; // 证件类型：显示值→编码
    private static final Map<String, String> TRAIN_TYPE_MAP; // 培训类别：显示值→编码
    private static final Map<String, String> EDUCATION_MAP; // 学历：显示值→编码

    // 初始化字典常量（根据实际业务填充，以下为示例）
    static {
        // 证件类型：key=显示值（如Excel中填写的内容），value=数据库存储的编码
        CERT_TYPE_MAP = new HashMap<>();
        CERT_TYPE_MAP.put("身份证", "IDCARD");
        CERT_TYPE_MAP.put("士官证", "SGCARD");
        CERT_TYPE_MAP.put("士兵证", "SBCARD");
        CERT_TYPE_MAP.put("其他证件", "OTCARD");

        // 培训类别：key=显示值，value=编码（示例中“复审”对应编码“3”，与后续判断一致）
        TRAIN_TYPE_MAP = new HashMap<>();
        TRAIN_TYPE_MAP.put("新训", "1");
        TRAIN_TYPE_MAP.put("复训", "2");
        TRAIN_TYPE_MAP.put("复审", "3");
        TRAIN_TYPE_MAP.put("二次考试", "4");

        // 学历：key=显示值，value=编码
        EDUCATION_MAP = new HashMap<>();
        EDUCATION_MAP.put("初中", "CZ");
        EDUCATION_MAP.put("高中", "GZ");
        EDUCATION_MAP.put("中专", "ZZ");
        EDUCATION_MAP.put("大专", "DZ");
        EDUCATION_MAP.put("本科", "BK");
        EDUCATION_MAP.put("硕士研究生", "CSYJS");
        EDUCATION_MAP.put("博士研究生", "BSYJS");
    }
}
